{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# [Tensor 介绍](https://www.paddlepaddle.org.cn/documentation/docs/zh/guides/beginner/tensor_cn.html)\n",
    "\n",
    "飞桨使用张量（[Tensor](https://www.paddlepaddle.org.cn/documentation/docs/api/paddle/Tensor_cn.html)） 来表示神经网络中传递的数据，Tensor 可以理解为**多维数组**，类似于 Numpy 数组（ndarray） 的概念。与 Numpy 数组相比，Tensor 除了支持运行在 CPU 上，还支持运行在 GPU 及各种 AI 芯片上，以实现计算加速；此外，飞桨基于 Tensor，实现了深度学习所必须的反向传播功能和多种多样的组网算子，从而可更快捷地实现深度学习组网与训练等功能。两者具体异同点可参见下文 Tensor 与 Numpy 数组相互转换。\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Tensor(shape=[3], dtype=float32, place=CUDAPlace(0), stop_gradient=True,\n",
      "       [2., 3., 4.]) paddle.float32\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python3.8/dist-packages/ipykernel/ipkernel.py:283: DeprecationWarning: `should_run_async` will not call `transform_cell` automatically in the future. Please pass the result to `transformed_cell` argument and any exception that happen during thetransform in `preprocessing_exc_tuple` in IPython 7.17 and above.\n",
      "  and should_run_async(code)\n",
      "/usr/local/lib/python3.8/dist-packages/paddle/tensor/creation.py:125: DeprecationWarning: `np.object` is a deprecated alias for the builtin `object`. To silence this warning, use `object` by itself. Doing this will not modify any behavior and is safe. \n",
      "Deprecated in NumPy 1.20; for more details and guidance: https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations\n",
      "  if data.dtype == np.object:\n"
     ]
    }
   ],
   "source": [
    "import warnings\n",
    "\n",
    "with warnings.catch_warnings():\n",
    "    warnings.simplefilter('ignore')\n",
    "    # 你的代码，这里的警告将被忽略\n",
    "\n",
    "## 指定数据创建\n",
    "import paddle\n",
    "ndim_1_Tensor = paddle.to_tensor([2.0, 3.0, 4.0])\n",
    "print(ndim_1_Tensor, ndim_1_Tensor.dtype)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python3.8/dist-packages/ipykernel/ipkernel.py:283: DeprecationWarning: `should_run_async` will not call `transform_cell` automatically in the future. Please pass the result to `transformed_cell` argument and any exception that happen during thetransform in `preprocessing_exc_tuple` in IPython 7.17 and above.\n",
      "  and should_run_async(code)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "(Tensor(shape=[1], dtype=int64, place=CUDAPlace(0), stop_gradient=True,\n",
       "        [2]),\n",
       " Tensor(shape=[1], dtype=int64, place=CUDAPlace(0), stop_gradient=True,\n",
       "        [2]))"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "paddle.to_tensor(2), paddle.to_tensor([2])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Tensor(shape=[2, 3], dtype=float32, place=CUDAPlace(0), stop_gradient=True,\n",
      "       [[1., 2., 3.],\n",
      "        [4., 5., 6.]])\n"
     ]
    }
   ],
   "source": [
    "ndim_2_Tensor = paddle.to_tensor([[1.0, 2.0, 3.0],\n",
    "                                  [4.0, 5.0, 6.0]])\n",
    "print(ndim_2_Tensor)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Tensor(shape=[2, 2, 5], dtype=int64, place=CUDAPlace(0), stop_gradient=True,\n",
      "       [[[1 , 2 , 3 , 4 , 5 ],\n",
      "         [6 , 7 , 8 , 9 , 10]],\n",
      "\n",
      "        [[11, 12, 13, 14, 15],\n",
      "         [16, 17, 18, 19, 20]]])\n"
     ]
    }
   ],
   "source": [
    "ndim_3_Tensor = paddle.to_tensor([[[1, 2, 3, 4, 5],\n",
    "                                   [6, 7, 8, 9, 10]],\n",
    "                                  [[11, 12, 13, 14, 15],\n",
    "                                   [16, 17, 18, 19, 20]]])\n",
    "print(ndim_3_Tensor)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](https://githubraw.cdn.bcebos.com/PaddlePaddle/docs/develop/docs/guides/01_paddle2.0_introduction/basic_concept/images/Tensor_2.0.png?raw=true)\n",
    "\n",
    "需要注意的是，Tensor 必须形如矩形，即在任何一个维度上，元素的数量必须相等，否则会抛出异常，示例如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# ndim_2_Tensor = paddle.to_tensor([[1.0, 2.0],\n",
    "#                                   [4.0, 5.0, 6.0]])\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 飞桨也支持将 Tensor 转换为 Python 序列数据，可通过 [paddle.tolist](https://www.paddlepaddle.org.cn/documentation/docs/api/paddle/tolist_cn.html) 实现，飞桨实际的转换处理过程是 Python 序列 <-> Numpy 数组 <-> Tensor。\n",
    "\n",
    "* 基于给定数据创建 Tensor 时，飞桨是通过拷贝方式创建，与原始数据不共享内存。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(Tensor(shape=[2, 3], dtype=float32, place=CUDAPlace(0), stop_gradient=True,\n",
       "        [[0., 0., 0.],\n",
       "         [0., 0., 0.]]),\n",
       " Tensor(shape=[2, 3], dtype=float32, place=CUDAPlace(0), stop_gradient=True,\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.]]),\n",
       " Tensor(shape=[2, 3], dtype=float32, place=CUDAPlace(0), stop_gradient=True,\n",
       "        [[10., 10., 10.],\n",
       "         [10., 10., 10.]]))"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "## 指定形状创建\n",
    "paddle.zeros([2, 3]), paddle.ones([2, 3]), paddle.full([2, 3], 10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Tensor(shape=[2, 3], dtype=float32, place=CUDAPlace(0), stop_gradient=True,\n",
       "       [[0., 0., 0.],\n",
       "        [0., 0., 0.]])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = paddle.zeros([2, 3])\n",
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Tensor(shape=[4], dtype=int64, place=CUDAPlace(0), stop_gradient=True,\n",
       "       [1, 2, 3, 4])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "## 指定区间创建\n",
    "paddle.arange(start=1, end=5, step=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Tensor(shape=[3, 224, 224], dtype=float32, place=CUDAPlace(0), stop_gradient=True,\n",
      "       [[[0.70588237, 0.89019614, 0.86274517, ..., 0.25882354, 0.65882355, 0.72549021],\n",
      "         [0.67843139, 0.22745100, 0.95294124, ..., 0.55686277, 0.35686275, 0.74901962],\n",
      "         [0.55294120, 0.72156864, 0.57647061, ..., 0.92549026, 0.23921570, 0.07058824],\n",
      "         ...,\n",
      "         [0.47450984, 0.18823531, 0.73725492, ..., 0.83529419, 0.52549022, 0.27450982],\n",
      "         [0.00392157, 0.07058824, 0.01960784, ..., 0.        , 0.38823533, 0.12941177],\n",
      "         [0.56470591, 0.        , 0.87058830, ..., 0.49411768, 0.51372552, 0.09803922]],\n",
      "\n",
      "        [[0.29803923, 0.16862746, 0.56862748, ..., 0.96078438, 0.55294120, 0.85490203],\n",
      "         [0.28627452, 0.85490203, 0.34509805, ..., 0.62352943, 0.25098041, 0.89803928],\n",
      "         [0.08627451, 0.69803923, 0.84705889, ..., 0.41568631, 0.48627454, 0.37647063],\n",
      "         ...,\n",
      "         [0.87843144, 0.08235294, 0.60000002, ..., 0.44313729, 0.34117648, 0.62745100],\n",
      "         [0.98823535, 0.09411766, 0.63137257, ..., 0.49803925, 0.70980394, 0.61568630],\n",
      "         [0.25882354, 0.34901962, 0.64705884, ..., 0.11764707, 0.24313727, 0.62745100]],\n",
      "\n",
      "        [[0.87843144, 0.68235296, 0.60784316, ..., 0.05882353, 0.33333334, 0.41960788],\n",
      "         [0.14509805, 0.39607847, 0.89803928, ..., 0.53333336, 0.09411766, 0.78823537],\n",
      "         [0.91372555, 0.98039222, 0.81568635, ..., 0.35686275, 0.81176478, 0.81568635],\n",
      "         ...,\n",
      "         [0.95294124, 0.18039216, 0.90196085, ..., 0.34509805, 0.45490199, 0.83529419],\n",
      "         [0.10588236, 0.30588236, 0.03137255, ..., 0.58823532, 0.95294124, 0.35294119],\n",
      "         [0.70588237, 0.18823531, 0.35686275, ..., 0.61960787, 0.30980393, 0.39607847]]])\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "from PIL import Image\n",
    "import paddle.vision.transforms as T\n",
    "import paddle.vision.transforms.functional as F\n",
    "\n",
    "fake_img = Image.fromarray((np.random.rand(224, 224, 3) * 255.).astype(np.uint8)) # 创建随机图片\n",
    "transform = T.ToTensor()\n",
    "tensor = transform(fake_img) # 使用 ToTensor()将图片转换为 Tensor\n",
    "print(tensor)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[7]\n",
      "Tensor(shape=[1, 1], dtype=int64, place=CUDAPinnedPlace, stop_gradient=True,\n",
      "       [[7]])\n"
     ]
    }
   ],
   "source": [
    "import paddle\n",
    "\n",
    "from paddle.vision.transforms import Compose, Normalize\n",
    "\n",
    "transform = Compose([Normalize(mean=[127.5],\n",
    "                               std=[127.5],\n",
    "                               data_format='CHW')])\n",
    "\n",
    "test_dataset = paddle.vision.datasets.MNIST(mode='test', transform=transform)\n",
    "print(test_dataset[0][1]) # 打印原始数据集的第一个数据的 label\n",
    "loader = paddle.io.DataLoader(test_dataset)\n",
    "for data in enumerate(loader):\n",
    "    x, label = data[1]\n",
    "    print(label) # 打印由 DataLoader 返回的迭代器中的第一个数据的 label\n",
    "    break\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "the shape of ndim_1_Tensor: [3]\n",
      "After reshape: [1, 3]\n"
     ]
    }
   ],
   "source": [
    "ndim_1_Tensor = paddle.to_tensor([1, 2, 3])\n",
    "print(\"the shape of ndim_1_Tensor:\", ndim_1_Tensor.shape)\n",
    "\n",
    "reshape_Tensor = paddle.reshape(ndim_1_Tensor, [1, 3])\n",
    "print(\"After reshape:\", reshape_Tensor.shape)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Tensor flattened to Vector: [ 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20]\n"
     ]
    }
   ],
   "source": [
    "print(\"Tensor flattened to Vector:\", paddle.reshape(ndim_3_Tensor, [-1]).numpy())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "origin_tensor name:  generated_tensor_28\n",
      "new_tensor name:  dygraph_tmp_29\n",
      "same_tensor name:  generated_tensor_28\n"
     ]
    }
   ],
   "source": [
    "origin_tensor = paddle.to_tensor([1, 2, 3])\n",
    "new_tensor = paddle.reshape(origin_tensor, [1, 3]) # 非原位操作\n",
    "same_tensor = paddle.reshape_(origin_tensor, [1, 3]) # 原位操作\n",
    "print(\"origin_tensor name: \", origin_tensor.name)\n",
    "print(\"new_tensor name: \", new_tensor.name)\n",
    "print(\"same_tensor name: \", same_tensor.name)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Tensor dtype of ndim_1_tensor: paddle.float64\n",
      "Tensor dtype from Python integers: paddle.int64\n",
      "Tensor dtype from Python floating point: paddle.float32\n"
     ]
    }
   ],
   "source": [
    "# 创建 Tensor 时指定 dtype\n",
    "ndim_1_tensor = paddle.to_tensor([2.0, 3.0, 4.0], dtype='float64')\n",
    "print(\"Tensor dtype of ndim_1_tensor:\", ndim_1_tensor.dtype)\n",
    "# 创建 Tensor 时不指定 dtype，自动选择对应的默认类型\n",
    "print(\"Tensor dtype from Python integers:\", paddle.to_tensor(1).dtype)\n",
    "print(\"Tensor dtype from Python floating point:\", paddle.to_tensor(1.0).dtype)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Tensor after cast to float64: paddle.float64\n",
      "Tensor after cast to int64: paddle.int64\n"
     ]
    }
   ],
   "source": [
    "float32_Tensor = paddle.to_tensor(1.0)\n",
    "\n",
    "float64_Tensor = paddle.cast(float32_Tensor, dtype='float64')\n",
    "print(\"Tensor after cast to float64:\", float64_Tensor.dtype)\n",
    "\n",
    "int64_Tensor = paddle.cast(float32_Tensor, dtype='int64')\n",
    "print(\"Tensor after cast to int64:\", int64_Tensor.dtype)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CPUPlace\n"
     ]
    }
   ],
   "source": [
    "cpu_Tensor = paddle.to_tensor(1, place=paddle.CPUPlace())\n",
    "print(cpu_Tensor.place)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CUDAPlace(0)\n"
     ]
    }
   ],
   "source": [
    "gpu_Tensor = paddle.to_tensor(1, place=paddle.CUDAPlace(0))\n",
    "print(gpu_Tensor.place) # 显示 Tensor 位于 GPU 设备的第 0 张显卡上\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Tensor name: generated_tensor_40\n"
     ]
    }
   ],
   "source": [
    "print(\"Tensor name:\", paddle.to_tensor(1).name)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Tensor stop_gradient: True\n",
      "Tensor stop_gradient: False\n"
     ]
    }
   ],
   "source": [
    "eg = paddle.to_tensor(1)\n",
    "print(\"Tensor stop_gradient:\", eg.stop_gradient)\n",
    "eg.stop_gradient = False\n",
    "print(\"Tensor stop_gradient:\", eg.stop_gradient)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
